import { useState, useRef } from "react";

import { Button, Table, Space, Form, Input, Popconfirm, DatePicker, Select } from "antd";
import {
  DeleteOutlined,
  ExportOutlined,
  SearchOutlined,
  SyncOutlined,
  EyeOutlined,
  DownOutlined,
  ReloadOutlined,
} from "@ant-design/icons";
import TableLayout, {
  SearchContainer,
  SearchAction,
  SearchForm,
  OperateContainer,
  MainContainer,
} from "@/components/templates/TableLayout";
import { Drawer, ButtonCollapsed } from "@/components/iteration";
import { AuthButton } from "@/components/auth";
import { useLoadPageData } from "@/hooks";
import {
  getLogOperationList,
  getLogOperation,
  deleteLogOperation,
  deleteBatchLogOperation,
} from "@/api/system/log/operation";
import PropTypes from "prop-types";

const AUTH_PERMISSION = {
  DELETE: "system:log:operation:delete",
  EXPORT: "system:log:peration:export",
};

const HeaderComponent = ({ onSearch, onReset }) => {
  const [folded, setFolded] = useState(false);
  const [searchType, setSearchType] = useState("keyword");
  const inputRef = useRef(null);
  const onFinish = (values) => {
    const data = Object.entries(values).filter(([_, value]) => !!value);
    data.length && onSearch(Object.fromEntries(data));
  };

  const hanldeSearch = () => {
    const value = inputRef.current.input.value;
    value && onSearch({ [searchType]: value });
  };

  const options = [
    { label: "综合搜索", value: "keyword", placeholder: "综合搜索" },
    { label: "模块名称", value: "moduleName", placeholder: "请输入模块名称" },
    { label: "方法名称", value: "methodName", placeholder: "请输入方法名称" },
    { label: "主机地址", value: "requestIp", placeholder: "请输入主机地址" },
    { label: "操作地点", value: "requestLocation", placeholder: "请输入操作地点" },
  ];

  return (
    <SearchContainer>
      <SearchAction>
        <Space.Compact>
          <Select
            defaultValue={searchType}
            style={{ width: 120 }}
            options={options}
            onChange={(v) => setSearchType(v)}
          />
          <Input ref={inputRef} placeholder={options.find((item) => item.value === searchType).placeholder} />
          <Button icon={<SearchOutlined />} onClick={hanldeSearch} />
        </Space.Compact>

        <ButtonCollapsed
          type="link"
          icon={<DownOutlined />}
          iconPosition="end"
          collapsed={folded}
          onClick={() => setFolded(!folded)}
        >
          高级搜索
        </ButtonCollapsed>
      </SearchAction>
      <SearchForm collapse={folded}>
        <Form layout="inline" autoComplete="off" onFinish={onFinish} onReset={onReset}>
          <Form.Item name="moduleName" label="模块名称">
            <Input placeholder="请输入模块名称" />
          </Form.Item>
          <Form.Item name="methodName" label="方法名称">
            <Input placeholder="请输入方法名称" />
          </Form.Item>
          <Form.Item name="requestIp" label="主机地址">
            <Input placeholder="请输入主机地址" />
          </Form.Item>
          <Form.Item name="requestLocation" label="操作地点">
            <Input placeholder="请输入操作地点" />
          </Form.Item>
          <Form.Item name="createTimes" label="操作时间">
            <DatePicker.RangePicker format="YYYY/MM/DD" />
          </Form.Item>
          <Form.Item>
            <Space>
              <Button type="primary" icon={<SearchOutlined />} htmlType="submit">
                搜索
              </Button>
              <Button icon={<SyncOutlined />} htmlType="reset">
                重置
              </Button>
            </Space>
          </Form.Item>
        </Form>
      </SearchForm>
    </SearchContainer>
  );
};
HeaderComponent.propTypes = {
  onSearch: PropTypes.func,
  onReset: PropTypes.func,
};

const OperateCompoent = ({ deleteDisabled, onBatchDelete, onRefresh }) => {
  return (
    <OperateContainer>
      <Space>
        <Popconfirm
          title="系统提示"
          description="是否确认删除多项用户的数据项？"
          onConfirm={onBatchDelete}
          okText="是"
          cancelText="否"
        >
          <AuthButton auth={AUTH_PERMISSION.DELETE} danger ghost icon={<DeleteOutlined />} disabled={deleteDisabled}>
            删除
          </AuthButton>
        </Popconfirm>
      </Space>
      <Space>
        <Button icon={<ReloadOutlined />} onClick={onRefresh} />
        <AuthButton auth={AUTH_PERMISSION.EXPORT} icon={<ExportOutlined />} href="operation/export" />
      </Space>
    </OperateContainer>
  );
};
OperateCompoent.propTypes = {
  deleteDisabled: PropTypes.bool,
  onBatchDelete: PropTypes.func,
  onRefresh: PropTypes.func,
};
const JsonFormatComponent = ({ value }) => {
  if (value) {
    return <pre className="json-card">{JSON.stringify(JSON.parse(value), null, 2)}</pre>;
  }

  return <>--无--</>;
};
JsonFormatComponent.propTypes = {
  value: PropTypes.string,
};

const DetailComponent = ({ value }) => {
  const [model, setModel] = useState(null);

  const options = [
    { label: "模块名称", value: "moduleName" },
    { label: "方法名称", value: "methodName" },
    { label: "方法路径", value: "methodPath" },
    { label: "请求方式", value: "requestMode" },
    { label: "主机地址", value: "requestIp" },
    { label: "操作地点", value: "requestLocation" },
    { label: "消耗时间", value: "costTime" },
    { label: "操作时间", value: "createTime" },
    { label: "操作状态", value: "status" },
    {
      label: "请求参数",
      value: "requestParam",
      render: (value) => <JsonFormatComponent value={value} />,
    },
    {
      label: "响应参数",
      value: "respondJson",
      render: (value) => <JsonFormatComponent value={value} />,
    },
  ];

  const onStatusChange = async (status) => {
    if (model || status === false) return;
    const res = await getLogOperation(value);
    setModel(res);
  };

  return (
    <Drawer
      button={{ label: "详情", type: "link", icon: <EyeOutlined /> }}
      drawer={{ title: "操作日志详细", width: "500px" }}
      onStatusChange={onStatusChange}
    >
      <div className="detail">
        {model &&
          options.map(({ label, value, render }) => (
            <div className="detail-item" style={{ marginBottom: "8px" }} key={value}>
              <span style={{ paddingRight: "12px" }}>{label}</span>
              {render ? render(model[value], options) : <span>{model[value]}</span>}
            </div>
          ))}
      </div>
    </Drawer>
  );
};
DetailComponent.propTypes = {
  value: PropTypes.string,
};

const TableComponent = ({ onDelete, ...resProps }) => {
  const columns = [
    { key: "moduleName", title: "模块名称", dataIndex: "moduleName" },
    { key: "methodName", title: "方法名称", dataIndex: "methodName" },
    { key: "requestIp", title: "主机地址", dataIndex: "requestIp" },
    { key: "requestLocation", title: "操作地点", dataIndex: "requestLocation" },
    { key: "status", title: "操作状态", dataIndex: "status" },
    { key: "costTime", title: "消耗时间", dataIndex: "costTime" },
    { key: "createTime", title: "操作时间", dataIndex: "createTime" },
    {
      title: "操作",
      key: "action",
      render: (_, record) => (
        <Space>
          <DetailComponent value={record.id} />
          <Popconfirm
            title="系统提示"
            description={`是否确认删除ID为${record.id}的数据项？`}
            onConfirm={() => onDelete(record.id)}
            okText="是"
            cancelText="否"
          >
            <Button type="link" danger icon={<DeleteOutlined />}>
              删除
            </Button>
          </Popconfirm>
        </Space>
      ),
    },
  ];
  return (
    <MainContainer>
      <Table size="middle" {...resProps} columns={columns} />
    </MainContainer>
  );
};
TableComponent.propTypes = {
  onDelete: PropTypes.func,
  resProps: PropTypes.object,
};

const GeneralComponent = () => {
  const {
    loading,
    dataSource,
    pagination,
    onSearchData, // 搜索数据
    onRefreshData,
    onResetData,
    onPageChange,
  } = useLoadPageData(getLogOperationList);
  const [selectedRowKeys, setSelectedRowKeys] = useState([]);

  const onDelete = async (value) => {
    await deleteLogOperation(value);
    onRefreshData();
    setSelectedRowKeys(selectedRowKeys.filter((item) => item !== value));
  };

  const onBatchDelete = async () => {
    if (!selectedRowKeys.length) return;
    await deleteBatchLogOperation(selectedRowKeys);
    onRefreshData();
    setSelectedRowKeys([]);
  };

  return (
    <TableLayout>
      <HeaderComponent onSearch={onSearchData} onReset={onResetData} />
      <OperateCompoent
        deleteDisabled={!selectedRowKeys.length}
        onBatchDelete={onBatchDelete}
        onRefresh={onRefreshData}
      />
      <TableComponent
        dataSource={dataSource}
        loading={loading}
        rowSelection={{
          selectedRowKeys,
          getCheckboxProps: ({ admin }) => ({ disabled: admin }),
          onChange: (v) => setSelectedRowKeys(v),
        }}
        pagination={{
          current: pagination.pageNum,
          pageSize: pagination.pageSize,
          total: pagination.totalPages,
          showSizeChanger: true,
          showTotal: (total) => `共${total}条`,
          onChange: onPageChange,
        }}
        onDelete={onDelete}
      />
    </TableLayout>
  );
};

export default GeneralComponent;
